package com.ylr.blog.framework.service.impl;

import com.ylr.blog.common.enums.BlogCodeEnum;
import com.ylr.base.common.exception.YlrException;
import com.ylr.blog.framework.service.BlogCodeService;
import com.ylr.redis.framework.service.RedisHashService;
import com.ylr.blog.common.constant.BlogConstant;
import com.ylr.base.common.utils.ThrottleUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2023-05-17 10:35:49
 * className: BlogCodeServiceImpl 博客编号生成服务接口
 * version: 1.0
 * description:
 */
@Service("blogCodeService")
@AllArgsConstructor
public class BlogCodeServiceImpl implements BlogCodeService {

    private static final Logger log = LoggerFactory.getLogger(BlogCodeServiceImpl.class);

    private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");

    private final RedisHashService redisHashService;

    private final ThrottleUtils throttleUtils;

    @Override
    public String generateCode(Long userId, Long blogId) {
        return this.generateCode(null, userId, blogId);
    }

    @Override
    public String generateCode(String type, Long userId, Long blogId) {
        /*
            博客编号生成规则：博客标识 + yyMMddHHmmss + 自增序列 + 用户标识
            业务标识：
                值：枚举值[YB YR YT YO]
                长度：2位
            用户标识：
                值：用户主键尾部四位数字，作为基因注入到博客编号中
                长度：4位
            博客标识：
                值：博客主键尾部两位数字，作为基因注入到博客编号中
                长度：2位
            yyMMddHHmmss：
                值：年月日时分秒
                长度：12位
            自增序列：
                值：redis自增序列
                长度：4位
            总长度：24位
         */
        StringBuilder sb = new StringBuilder(22);
        // 1、业务标识
        if (StringUtils.isEmpty(type)) {
            type = BlogCodeEnum.YB.name();
        }
        if (type.length() > 2) {
            log.error("博客标识长度不能超过两位字符。userId={} type={}", userId, type);
            throw new YlrException();
        }
        sb.append(type);

        // 2、用户标识
        String userIdSuffix = String.valueOf(userId % 10000);
        sb.append("0".repeat(Math.max(0, 4 - userIdSuffix.length())));
        sb.append(userIdSuffix);

        // 3、博客标识
        String blogIdSuffix = String.valueOf(blogId % 100);
        sb.append("0".repeat(Math.max(0, 2 - blogIdSuffix.length())));
        sb.append(userIdSuffix);

        String date = dateTimeFormatter.format(LocalDateTime.now());
        // 4、yyMMddHHmmss
        sb.append(date);

        // 获取自增值
        Long value = redisHashService.increment(BlogConstant.BLOG_CODE_MAP, date, 1);
        String val = value.toString();
        int length = val.length();
        // 5、自增序列
        sb.append("0".repeat(Math.max(0, 4 - length)));
        sb.append(val, 0, Math.min(4, length));

        // 节流执行，删除自增序列
        throttleUtils.throttleRun(() -> {
            // 延迟删除自增序列key
            redisHashService.delete(BlogConstant.BLOG_CODE_MAP, date);
        }, date, 1500, TimeUnit.MILLISECONDS);

        return sb.toString();
    }

    @Override
    public String replaceCodeType(String newType, String code) {
        StringBuilder sb = new StringBuilder(code);
        sb.replace(0, 2, newType);
        return sb.toString();
    }

//    public static void main(String[] args) {
//
//        AtomicLong atomicLong = new AtomicLong(1213);
//
//        int size = 10;
//        for (int i = 0; i < size; i++) {
//            long userId = IdWorker.getId();
//            System.out.println("userId=" + userId);
//            StringBuilder sb = new StringBuilder(22);
//            // 1、博客标识
//            String type = "YB";
//            sb.append(type);
//
//            // 2、用户标识
//            String userIdSuffix = String.valueOf(userId % 10000);
//            sb.append("0".repeat(Math.max(0, 4 - userIdSuffix.length())));
//            sb.append(userIdSuffix);
//
//            String date = dateTimeFormatter.format(LocalDateTime.now());
//            // 3、yyMMddHHmmss
//            sb.append(date);
//
//            // 获取自增值
//            long value = atomicLong.incrementAndGet();
//
//            String val = Long.toString(value);
//            // 4、自增序列
//            sb.append("0".repeat(Math.max(0, 4 - val.length())));
//            sb.append(val);
//
//            System.out.println("sb = " + sb);
//            System.out.println("--------------");
//        }
//
//    }

}
